package top.zhangjianyong.tools.utils;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.locks.ReentrantLock;
import java.util.function.Supplier;

/**
 * @author zhangjianyong
 * @since 2025/4/1 下午4:58
 */
public class LockUtil {

    private final static Map<String, ReentrantLock> LOCK_MAP = new ConcurrentHashMap<>();
    private static final Logger log = LoggerFactory.getLogger(LockUtil.class);

    private static void lock(String lockKey) {
        ReentrantLock lock = LOCK_MAP.computeIfAbsent(lockKey, k -> new ReentrantLock());
        lock.lock();
    }

    private static void unlock(String lockKey) {
        ReentrantLock lock = LOCK_MAP.get(lockKey);
        if (lock != null && lock.isHeldByCurrentThread()) {
            lock.unlock();
        }
    }

    public static <T> T excecute(String lockKey, Supplier<T> supplier) {
        lock(lockKey);
        try {
            return supplier.get();
        } finally {
            unlock(lockKey);
        }
    }

    public enum LockKey {
        STOCK_GOODS("STOCK_GOODS"),
        ;
        private final String prefix;

        LockKey(String prefix) {
            this.prefix = prefix;
        }

        public String getLockKey(Long id) {
            return prefix + "-" + id;
        }
    }

    public static void main(String[] args) {

        for (int i = 0; i < 100; i++) {
            new Thread(() -> {
                try {
                    lock("text");
                    System.out.println(Thread.currentThread().getName() + ":lock1");
                    lock("text");
                    System.out.println(Thread.currentThread().getName() + ":lock2");
                } catch (Exception e) {
                    log.error(e.getMessage(), e);
                } finally {
                    unlock("text");
                    System.out.println(Thread.currentThread().getName() + ":unlock");
                }
            }).start();
        }
    }
}
